#include "stdafx.h"
#include "gp_Pnt.h"
#include "gp_Dir.h"
#include "gp_Ax2.h"
#include "gp_Trsf.h"
#include "gp_Vec.h"
#include "gp_Ax1.h"
#include "gp.h"

bool gp_Ax1::IsCoaxial
	(const gp_Ax1& Other, 
	const double AngularTolerance,
	const double LinearTolerance) const
{
	gp_XYZ XYZ1 = loc.XYZ();
	XYZ1.Subtract (Other.loc.XYZ());
	XYZ1.Cross (Other.vdir.XYZ());
	double D1 = XYZ1.Modulus();
	gp_XYZ XYZ2 = Other.loc.XYZ();
	XYZ2.Subtract (loc.XYZ());
	XYZ2.Cross (vdir.XYZ());
	double D2 = XYZ2.Modulus();
	return (vdir.IsEqual (Other.vdir, AngularTolerance) &&
		D1 <= LinearTolerance && D2 <= LinearTolerance);
}

void gp_Ax1::Mirror (const gp_Pnt& P)
{
	loc.Mirror(P);
	vdir.Reverse();
}

gp_Ax1 gp_Ax1::Mirrored (const gp_Pnt& P) const
{
	gp_Ax1 A1 = *this;    
	A1.Mirror (P);
	return A1;
}

void gp_Ax1::Mirror (const gp_Ax1& A1)
{
	loc.Mirror(A1);
	vdir.Mirror(A1.vdir);
}

gp_Ax1 gp_Ax1::Mirrored (const gp_Ax1& A1) const
{
	gp_Ax1 A = *this;
	A.Mirror (A1);
	return A;
}

void gp_Ax1::Mirror (const gp_Ax2& A2)
{
	loc.Mirror  (A2);
	vdir.Mirror (A2);
}

gp_Ax1 gp_Ax1::Mirrored (const gp_Ax2& A2) const
{
	gp_Ax1 A1 = *this;
	A1.Mirror (A2);
	return A1;
}
 gp_Ax1::gp_Ax1() : loc(0.,0.,0.), vdir(0.,0.,1.)
{ }

 gp_Ax1::gp_Ax1 (const gp_Pnt& P,
		       const gp_Dir& V) :  loc(P), vdir(V)
{ }

 void gp_Ax1::SetDirection (const gp_Dir& V)
{ vdir = V; }

 void gp_Ax1::SetLocation (const gp_Pnt& P)
{ loc = P; }

 const gp_Dir& gp_Ax1::Direction () const
{ return vdir; }

 const gp_Pnt& gp_Ax1::Location () const
{ return loc; }

 bool gp_Ax1::IsNormal
(const gp_Ax1& Other,
 const double AngularTolerance) const
{ return vdir.IsNormal(Other.vdir, AngularTolerance); }

 bool gp_Ax1::IsOpposite
(const gp_Ax1& Other,
 const double AngularTolerance) const
{ return vdir.IsOpposite(Other.vdir, AngularTolerance); }

 bool gp_Ax1::IsParallel
(const gp_Ax1& Other,
 const double AngularTolerance) const
{ return vdir.IsParallel(Other.vdir, AngularTolerance); }

 double gp_Ax1::Angle (const gp_Ax1& Other) const
{ return vdir.Angle (Other.vdir); }

 void gp_Ax1::Reverse ()
{ vdir.Reverse(); }

 gp_Ax1 gp_Ax1::Reversed () const
{ 
  gp_Dir D = vdir.Reversed();   
  return gp_Ax1(loc, D);
}

 void gp_Ax1::Rotate (const gp_Ax1& A1, const double Ang)
{
  loc.Rotate(A1, Ang);
  vdir.Rotate(A1 , Ang);
}
 
 gp_Ax1 gp_Ax1::Rotated (const gp_Ax1& A1,
			const double Ang) const
{
  gp_Ax1 A = *this;
  A.Rotate (A1, Ang);
  return A;
}

 void gp_Ax1::Scale (const gp_Pnt& P,
		    const double S)
{
  loc.Scale (P, S);
  if (S < 0.0)  vdir.Reverse();
}

 gp_Ax1 gp_Ax1::Scaled (const gp_Pnt& P,
		       const double S) const
{
  gp_Ax1 A1 = *this;
  A1.Scale (P, S);
  return A1;
}

 void gp_Ax1::Transform (const gp_Trsf& T)
{ 
   loc.Transform(T); 
   vdir.Transform(T);
}

 gp_Ax1 gp_Ax1::Transformed (const gp_Trsf& T) const
{
  gp_Ax1 A1 = *this;
  A1.Transform (T);
  return A1;
}

 void gp_Ax1::Translate (const gp_Vec& V)
{ loc.Translate (V); }

 gp_Ax1 gp_Ax1::Translated (const gp_Vec& V) const
{
  gp_Ax1 A1 = *this;
  (A1.loc).Translate (V); 
  return A1;
}

 void gp_Ax1::Translate (const gp_Pnt& P1,
			       const gp_Pnt& P2)
{
  loc.Translate (P1, P2);
}

 gp_Ax1 gp_Ax1::Translated (const gp_Pnt& P1,
			   const gp_Pnt& P2) const
{
  gp_Ax1 A1 = *this;
  (A1.loc).Translate (P1, P2);
  return A1;
}

